OpenCV4 目标跟踪(二)《详解稀疏光流、稠密光流》

您所在的位置:网站首页 opencv 光流法 对齐 OpenCV4 目标跟踪(二)《详解稀疏光流、稠密光流》

OpenCV4 目标跟踪(二)《详解稀疏光流、稠密光流》

2024-07-12 10:33| 来源: 网络整理| 查看: 265

作者:RayChiu_Labloy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

目录

光流定义:

光流的应用领域:

光流法基本原理 

基本假设条件:

(1)亮度恒定

(2)小运动

 基本约束方程:

按照理论基础与数学方法的区分得几种光流估计算法的简介

基于梯度的方法

基于匹配的方法

基于能量的方法

基于相位的方法

根据所形成的光流场中二维矢量疏密程度区分的稠密、稀疏光流

 稀疏光流:

关于稀疏光流的描述 

稀疏光流的相关函数calcOpticalFlowPyrLK()

官方测试代码:

稠密光流: 

关于稠密光流的描述 

相关函数calcOpticalFlowFarneback()

官方测试代码:

Lucas-Kanade(LK)光流法

最初的LK: 

增加空间一致假设的初衷:

约束方程:

改进后的金字塔LK光流法 

为什么要用金字塔

Lucas-Kanade改进算法处理的步骤: 

meanshift和camshift对于视频跟踪还是有一定局限性,现在尝试用光流估计法试试。

光流定义:

        光流(optical flow)是空间运动物体在观察成像平面上的像素运动的瞬时速度。

        光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。

        通常将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。

        说白了,所谓光流就是瞬时速率,在时间间隔很小(比如视频的连续前后两帧之间)时,也等同于目标点的位移

        它显示了一个球在5个连续帧里的移动。箭头显示了它的位移矢量。

光流的应用领域: 移动构建视频压缩视频稳定 光流法基本原理  基本假设条件: (1)亮度恒定

        就是同一点随着时间的变化,其亮度不会发生改变。这是基本光流法的假定(所有光流法变种都必须满足),用于得到光流法基本方程;

(2)小运动

        这个也必须满足,就是时间的变化不会引起位置的剧烈变化,这样灰度才能对位置求偏导(换句话说,小运动情况下我们才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数),这也是光流法不可或缺的假定;

 基本约束方程:

        考虑一个像素I(x,y,t)在第一帧的光强度(其中t代表其所在的时间维度)。它移动了 (dx,dy)的距离到下一帧,用了dt时间。因为是同一个像素点,依据上文提到的第一个假设我们认为该像素在运动前后的光强度是不变的,即:

右侧泰勒展开得: 

 其中ε代表二阶无穷小项,可忽略不计。从这个方程中我们可以得到:

 设u,v分别为光流分别为沿X轴与Y轴的速度矢量,得:

令 

 分别表示图像中像素点的灰度沿X,Y,T方向的偏导数。

综上,式(3)可以写为:

 其中,Ix,Iy,It均可由图像数据求得,而(u,v)即为所求光流矢量。

        约束方程只有一个,而方程的未知量有两个,这种情况下无法求得u和v的确切值。此时需要引入另外的约束条件,从不同的角度引入约束条件,导致了不同光流场计算方法。按照理论基础与数学方法的区别把它们分成四种:

基于梯度(微分)的方法基于匹配的方法基于能量(频率)的方法基于相位的方法和神经动力学方法。 按照理论基础与数学方法的区分得几种光流估计算法的简介 基于梯度的方法

        基于梯度的方法又称为微分法,它是利用时变图像灰度(或其滤波形式)的时空微分(即时空梯度函数)来计算像素的速度矢量。

        由于计算简单和较好的结果,该方法得到了广泛应用和研究。典型的代表是Horn-Schunck算法与Lucas-Kanade(LK)算法。

        Horn-Schunck算法在光流基本约束方程的基础上附加了全局平滑假设,假设在整个图像上光流的变化是光滑的,即物体运动矢量是平滑的或只是缓慢变化的。

        基于此思想,大量的改进算法不断提出。Nagel采用有条件的平滑约束,即通过加权矩阵的控制对梯度进行不同平滑处理;Black和Anandan针对多运动的估计问题,提出了分段平滑的方法。

基于匹配的方法

        基于匹配的光流计算方法包括基于特征和区域的两种。

        基于特征的方法不断地对目标主要特征进行定位和跟踪,对目标大的运动和亮度变化具有鲁棒性。存在的问题是光流通常很稀疏,而且特征提取和精确匹配也十分困难。

        基于区域的方法先对类似的区域进行定位,然后通过相似区域的位移计算光流。这种方法在视频编码中得到了广泛的应用。然而,它计算的光流仍不稠密。另外,这两种方法估计亚像素精度的光流也有困难,计算量很大。

基于能量的方法

        基于能量的方法又称为基于频率的方法,在使用该类方法的过程中,要获得均匀流场的准确的速度估计,就必须对输入的图像进行时空滤波处理,即对时间和空间的整合,但是这样会降低光流的时间和空间分辨率。基于频率的方法往往会涉及大量的计算,另外,要进行可靠性评价也比较困难。

基于相位的方法

        基于相位的方法是由Fleet和Jepson提出的,Fleet和Jepson最先提出将相位信息用于光流计算的思想。当我们计算光流的时候,相比亮度信息,图像的相位信息更加可靠,所以利用相位信息获得的光流场具有更好的鲁棒性。基于相位的光流算法的优点是:对图像序列的适用范围较宽,而且速度估计比较精确,但也存在着一些问题:第一,基于相位的模型有一定的合理性,但是有较高的时间复杂性;第二,基于相位的方法通过两帧图像就可以计算出光流,但如果要提高估计精度,就需要花费一定的时间;第三,基于相位的光流计算法对图像序列的时间混叠是比较敏感的。

根据所形成的光流场中二维矢量疏密程度区分的稠密、稀疏光流  稀疏光流: 关于稀疏光流的描述 

        相对于稠密光流,它通常需要指定一组点进行跟踪,这组点最好具有某种明显的特性,例如Harris角点等,那么跟踪就会相对稳定和可靠。稀疏跟踪的计算开销比稠密跟踪小得多。

 (绿色为跟踪点效果)

        上文提到的基于特征的匹配方法是典型的属于稀疏光流的算法。

稀疏光流的相关函数calcOpticalFlowPyrLK() void cv::calcOpticalFlowPyrLK(InputArrayprevImg,InputArraynextImg,InputArrayprevPts,InputOutputArraynextPts,OutputArraystatus,OutputArrayerr,SizewinSize = Size(21, 21),int maxLevel = 3,TermCriteriacriteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),int flags = 0,double minEigThreshold = 1e-4 )

参数解释: prevImg--> 上一帧图片; nextImg--> 当前帧图片; prevPts--> 上一帧找到的特征点向量; nextPts--> 与返回值中的nextPtrs相同; status--> 与返回的status相同; err--> 与返回的err相同; winSize--> 在计算局部连续运动的窗口尺寸(在图像金字塔中),default=Size(21, 21); maxLevel--> 图像金字塔层数,0表示不使用金字塔, default=3; criteria--> 寻找光流迭代终止的条件; flags--> 有两个宏,表示两种计算方法,分别是OPTFLOW_USE_INITIAL_FLOW表示使用估计值作为寻找到的初始光流,OPTFLOW_LK_GET_MIN_EIGENVALS表示使用最小特征值作为误差测量,default=0; minEigThreshold--> 该算法计算光流方程的2×2规范化矩阵的最小特征值,除以窗口中的像素数; 如果此值小于minEigThreshold,则会过滤掉相应的功能并且不会处理该光流,因此它允许删除坏点并获得性能提升, default=1e-4.

返回值: nextPtrs--> 输出一个二维点的向量,这个向量可以是用来作为光流算法的输入特征点,也是光流算法在当前帧找到特征点的新位置(浮点数); status--> 标志,在当前帧当中发现的特征点标志status==1,否则为0; err--> 向量中的每个特征对应的错误率.

实现原理: 在第一帧图像中检测Shi-Tomasi角点,使用LK算法来迭代的跟踪这些特征点。迭代的方式就是不断向CV2.calcOpticalFlowPyrLK()中传入上一帧图片的特征点以及当前帧的图片。函数会返回当前帧的点,这些点带有状态1或者0,如果在当前帧找到了上一帧中的点,那么这个点的状态就是1,否则就是0。

实现流程: · 加载视频。 · 调用CV2.GoodFeaturesToTrack 函数寻找兴趣点(关键点)。 · 调用CV2.CalcOpticalFlowPyrLK 函数计算出两帧图像中兴趣点的移动情况。 · 删除未移动的兴趣点。 · 在两次移动的点之间绘制一条线段。

官方测试代码: #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/videoio.hpp" #include "opencv2/highgui.hpp" #include #include using namespace cv; using namespace std; static void help() { // print a welcome message, and the OpenCV version cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3